﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System;

namespace BrainTechLLC
{
    public static class ConversionAndConditionals
    {
        /// <summary>
        /// Performs specified Action if object is of type t
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <param name="t"></param>
        /// <param name="del"></param>
        /// <returns></returns>
        public static bool DoIfType<T>(this object o, Type t, Action<T> del) where T : class
        {
            if (typeof(T).IsAssignableFrom(t)) { del(o as T); return true; }
            return false;
        }

        /// <summary>
        /// Performs the specified action on all elements of the array if o is an array type
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <param name="del"></param>
        /// <returns></returns>
        public static bool ForEachIfArray<T>(this object o, Action<T> del) where T : class
        {
            return o.ForEachIfArray(o.GetType(), del);
        }

        public static bool ForEachIfArray<T>(this object o, Type t, Action<T> del) where T : class
        {
            if (t.IsArray)
            {
                Array a = o as Array;
                foreach (object item in a) { del(item as T); }
                return true;
            }

            return false;
        }

        /// <summary>
        /// If the item of type T2 is null, returns default(T1).  Otherwise returns the result of the specified function.
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="item"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static T1 IfNotNull<T1, T2>(this T2 item, Func<T2, T1> func) where T2 : class
        {
            if (item == null)
                return default(T1);

            return func(item);
        }

        /// <summary>
        /// Determines if the string is a valid long and not equal to long.MinValue
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsLong(this string s)
        {
            return (s.ValueIfLong() != long.MinValue);
        }

        /// <summary>
        /// Retrieves the long value of the string if it's a long, otherwise returns long.MinValue
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static long ValueIfLong(this string s)
        {
            long conversionCheck;
            return (long.TryParse(s, out conversionCheck)) ? conversionCheck : long.MinValue;
        }

        /// <summary>
        /// Formats a string, truncating at maxLen.  If string has length greater than maxLen, optional elipses can be added (via addElipses = true)
        /// </summary>
        /// <param name="s"></param>
        /// <param name="maxLen"></param>
        /// <param name="addElipses"></param>
        /// <returns></returns>
        public static string MaxLength(this string s, int maxLen, bool addElipses)
        {
            if (string.IsNullOrEmpty(s))
                return string.Empty;

            int len = s.Length;

            if (len > maxLen)
            {
                if (addElipses && maxLen > 4)
                    return s.Substring(0, maxLen - 3) + "...";
                else
                    return s.Substring(0, maxLen);
            }

            return s;
        }

        /// <summary>
        /// If the object is null, return null.
        /// Otherwise, perform function del on the object and cast result to type T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <param name="del"></param>
        /// <returns></returns>
        public static T WithStringIfNotNull<T>(this object o, Func<object, T> del)
            where T : class
        {
            if (o == null)
                return null;

            return del(o.ToString()) as T;
        }

        /// <summary>
        /// If the object is null, return null.
        /// Otherwise, perform function del on the object's .ToString() value and cast result to type T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <param name="del"></param>
        /// <returns></returns>
        public static T WithStringIfNotNull<T>(this object o, Func<string, T> del)
            where T : class
        {
            if (o == null)
                return null;

            return del(o.ToString());
        }
    }
}